package controller;

import model.Table;
import controller.GameSetUp;

public class Winner {
	private static final int LOWER_LIMIT_MEDIUM_TABLE = 3;
	private static final int UPPER_LIMIT_MEDIUM_TABLE = 10;
	private static final int SMALL_TABLE = 3;
	private int winComb;
	Table td = new Table(GameSetUp.TABLE_SIZE);
	public Winner() {
		setWinComb();
	}

	public int getWinComb() {
		return winComb;
	}

	private void setWinComb() {
		if (GameSetUp.TABLE_SIZE == SMALL_TABLE)
			this.winComb = 3;
		else if (GameSetUp.TABLE_SIZE <= UPPER_LIMIT_MEDIUM_TABLE
				&& GameSetUp.TABLE_SIZE > LOWER_LIMIT_MEDIUM_TABLE)
			this.winComb = 4;
		else 
			this.winComb = 5;
	}



	public boolean searchForWinner(int row, int col,char mark) {
		char[][] array = td.getArray().clone();
		int numOfMarks=0;
		
		numOfMarks = rowsCheckForWinner(col, mark, array, numOfMarks);
		if(hasWinner(numOfMarks)) return true;
		numOfMarks = 0;
		numOfMarks = columnsCheckForWinner(row, mark, array, numOfMarks);
		if(hasWinner(numOfMarks)) return true;

		numOfMarks = 0;
		numOfMarks = checkStraightDiagonalForWinner(row, col, mark, array,
				numOfMarks);
		if(hasWinner(numOfMarks)) return true;
		numOfMarks = 0;
		numOfMarks = checkReverseDiagonalForWinner(row, col, mark, array,
				numOfMarks);
		if(hasWinner(numOfMarks)) return true;
		
		return false;		
	}

	private int checkReverseDiagonalForWinner(int row, int col, char mark,
			char[][] array, int numOfMarks) {
		if((row+col)<GameSetUp.TABLE_SIZE){
				int startingCol = row+col;
				int startingRow = 0;
				int cellsToCheck = (col+row)+1;
				for(int i = 0; i<cellsToCheck;i++){
					if(array[startingRow+i][startingCol-i]==mark){
						numOfMarks++;
						System.out.println(numOfMarks);
						System.out.println(startingRow+i);
						System.out.println(startingCol-i);
					} else {
						numOfMarks=0;
					}
					if(hasWinner(numOfMarks)) break;
				}
			} else {
				int startingCol = GameSetUp.TABLE_SIZE-1;
				int startingRow = (row+col)-(GameSetUp.TABLE_SIZE-1);
				int allCellsToCheck = GameSetUp.TABLE_SIZE-startingRow;
				for(int i = 0; i<allCellsToCheck;i++){
					if(array[startingRow+i][startingCol-i]==mark){
						numOfMarks++;
						System.out.println(numOfMarks);
					} else {
						numOfMarks=0;
					}
					if(hasWinner(numOfMarks)) break;
				}
			}
			return numOfMarks;
	}

	private int checkStraightDiagonalForWinner(int row, int col, char mark,
			char[][] array, int numOfMarks) {
		if((row-col)>=0){
			int startingRow = row-col;
			int endingRow = (GameSetUp.TABLE_SIZE) - startingRow;
			int startingCol = 0;
			for(int i = 0; i<endingRow;i++){
				if(array[startingRow+i][startingCol+i]==mark){
					numOfMarks++;
				} else {
					numOfMarks=0;
				}
				if(hasWinner(numOfMarks)) break;
			}
		} else {
			int startingRow = 0;
			int startingCol = col-row;
			int endingCol = (GameSetUp.TABLE_SIZE) - startingCol;
			for(int i = 0; i<endingCol;i++){
				if(array[startingRow+i][startingCol+i]==mark){
					numOfMarks++;
				} else {
					numOfMarks=0;
				}
				if(hasWinner(numOfMarks)) break;
			}
		}
		return numOfMarks;
	}

	private int rowsCheckForWinner(int col, char mark, char[][] array,
			int numOfMarks) {
		for(int i = 0; i<array.length;i++){
			if(array[i][col]==mark){
				numOfMarks++;
			} else {
				numOfMarks = 0;
			}
			if(hasWinner(numOfMarks)) break;
		}
		return numOfMarks;
	}

	private int columnsCheckForWinner(int row, char mark, char[][] array, int numOfMarks) {
		for(int i = 0; i<array.length;i++){
			if(array[row][i]==mark){
				numOfMarks++;
			} else {
				numOfMarks = 0;
			}
			if(hasWinner(numOfMarks)) break;
		}
		return numOfMarks;
	}
	
	private boolean hasWinner(int numOfMarks) {
		if(numOfMarks==getWinComb()){
			return true;
		}
		return false;
	}
}
